import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import { ElMessage } from 'element-plus'
import type { RouteRecordRaw } from 'vue-router';
import type { reqUserInfoReturnType } from "@/api/userInfo"
import { requestLogin, requestUserInfo, requestLogout } from "@/api/userInfo"
import type { reqLoginParamsType } from "@/api/userInfo"

//引入所以路由
import { staticRoutes, allAsyncRoutes, anyRoutes } from "@/router/routes"
//引入深拷贝
import cloneDeep from 'lodash/cloneDeep';
//引入路由器对象
import router from "@/router"



//1.从动态路由表得到有权限的路由表
function getMayroutes(asyncRoutes: RouteRecordRaw[], allroutes: string[]) {
  return asyncRoutes.filter((item) => {
    
    //如果当前路由的name在权限表中则返回
    if (allroutes.includes(item.name as string)) {;
      
      if (item.children && item.children.length > 0) {
        //递归处理子路由，重新赋值给子路由
        item.children = getMayroutes(item.children, allroutes)
      }

      return true
    }
  })
}

//2.封装函数把得到有权限的路由和任意路由插入到已经注册的路由器对象中
function toAppRouter(routes: RouteRecordRaw[]) {
  routes.forEach((item) => {
    router.addRoute(item)
  })
}


//3.退出登录先清空上一个用户所以的路由表,在重新插入静态路由
function deleteLastRoutes(routes: RouteRecordRaw[]) {
  //删除所有路由
  routes.forEach((item) => {
    router.removeRoute(item.name as string)
  })
  //插入静态路由
  staticRoutes.forEach((item) => {
    router.addRoute(item)
  })
}


/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
//定义用户信息模块数据的类型
export interface userInfoStateType {
  token: string;
  userInfo: reqUserInfoReturnType;
  menuRoutes: RouteRecordRaw[];
}
export const useUserInfoStore = defineStore('userInfo', {
  state: (): userInfoStateType => ({
    token: (getToken() as string) || '',
    userInfo: {
      routes: [],
      buttons: [],
      roles: [],
      name: "",
      avatar: "",
    },
    //把静态路由表保存起来，在侧边栏中遍历生成元素
    menuRoutes: staticRoutes
  }),

  actions: {
    //1.登录的方法
    async login(userInfo: reqLoginParamsType) {
      try {
        //发送登录请求
        const result = await requestLogin(userInfo)
        //把请求回来的token保存在state中
        this.token = result.token
        //持久化
        setToken(this.token)
      } catch (e) {
        //如果请求失败则返回失败的Promise实例,在哪里调用这个方法，就会在哪里处理
        return Promise.reject(e)
      }
    },

    //2.获取用户信息的方法
    async getInfo() {
      try {
        //方法用户信息请求
        const result = await requestUserInfo()
        //把请求回来的用户信息保存在state中
        this.userInfo = result
       
        //<1>.请求用户信息后拿，从动态路由表中过滤出有权限的路由
        const newStaticRoutes = getMayroutes(cloneDeep(allAsyncRoutes), result.routes)
        
        //<2>.把得到的路由表和任意路由插入app
        toAppRouter(newStaticRoutes.concat(anyRoutes))

        //<3>.重新给menuRoutes赋值静态路由表，展示菜单
        this.menuRoutes = staticRoutes.concat(newStaticRoutes, anyRoutes) 

        console.log(router.getRoutes());
        

      } catch (e) {
        //抛出异常
        return Promise.reject(e)
      }
    },

    //3.退出登录的方法
    async getLogot() {
      try {
        //方法退出登录请求
        await requestLogout()
        //退出的，登录后清空用户信息
        this.reset()


        //<4>.退出登录先清空上一个用户所以的路由表,在重新插入静态路由
        const routes = router.getRoutes()
        deleteLastRoutes(routes)


      } catch (e) {
        //抛出异常
        return Promise.reject(e)
      }
    },

    //4.在权限校验中，有token去请求用户名如果失败，就清空用户信息回到login页
    reset() {
      //删除本地中保存的token
      removeToken()
      //清空state中的用户信息
      this.token = ''
      this.userInfo = {
        routes: [],
        buttons: [],
        roles: [],
        name: "",
        avatar: "",
      }
    }
  },

});
